package com.mdhw.config;

import com.mdhw.common.enums.MessageEnum;
import com.mdhw.common.exception.BusException;
import com.mdhw.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.UUID;

@Slf4j
@Component
public class RepeatInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;

    @Value("${repeat.request.timeout}")
    private  int timeout;

    private static final String FORM_LOCK = "form_lock";


    //主要是这个方法中实现拦截逻辑
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        log.info("已经进入拦截器");
        String requestMode = request.getMethod();
        if("GET".equals(requestMode)){
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        String className = method.getDeclaringClass().getName();
        String methodName = method.getName();
        String methodKey = String.format("%s#%s", className, methodName);
        int methodHashCode = Math.abs(methodKey.hashCode());
        Enumeration enu=request.getParameterNames();
        StringBuilder sb = new StringBuilder();
        while(enu.hasMoreElements()){
            String paraName=(String)enu.nextElement();
//            System.out.println(paraName+": "+request.getParameter(paraName));
            sb.append(request.getParameter(paraName));
        }
        String s1 = sb.toString();
        int paramHashCode = Math.abs(s1.hashCode());
        String key = String.format("%s:%d_%d", FORM_LOCK, methodHashCode, paramHashCode);

        if (timeout <= 0) {
            timeout = 3;  // 默认3秒
        }
        boolean isSet = redisUtil.setIfAbsent(key, UUID.randomUUID().toString(), timeout);
        if (!isSet) {
            log.info("├ [表单重复提交] methodKey={},methodHashCode={}, paramHashCode={}, key={},", methodKey, methodHashCode,
                    paramHashCode, key);
            resolver.resolveException(request, response,
                    null, new BusException(MessageEnum.DUPLICATE_POST_ERROR));
            return false;
        }
        return true;
    }

//    @Override
//    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//    }

//    @Override
//    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//        log.info("-----------------------334343--------------------------");
//    }
}

